package com.biz.ssm.security;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.biz.ssm.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
public class JWTAuthenticationFilter extends BasicAuthenticationFilter {

    public JWTAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            String secret = JwtUtils.SECRET;
            String token = request.getHeader(JwtUtils.Authorization);
            if (null != secret && null != token) {
                String subject = JwtUtils.getSubject(token , secret);
                if (null != subject) {
                    // 如果请求头中有token，则进行解析，并且设置认证信息
                    MyAuthenticationJWTToken authenticationToken = getAuthentication(subject);
                    if (null != authenticationToken) {
                        SecurityContextHolder.getContext().setAuthentication(authenticationToken);
                    }
                }
            }
        } catch (Exception e) {

        } finally {
            chain.doFilter(request, response);
        }


    }
    /**
     * 这里从token中获取用户信息并新建一个token
     */
    @SuppressWarnings("unchecked")
    private MyAuthenticationJWTToken getAuthentication(String subject) {
        if (null != subject) {
            JSONObject object = JSON.parseObject(subject);
            JSONArray jsonArray = object.getJSONArray("authorities");
            List<JSONObject> list = jsonArray.toJavaList(JSONObject.class);
            List<GrantedAuthority> grantedAuthorities = new ArrayList<>();
            for (JSONObject authority : list) {
                grantedAuthorities.add(new SimpleGrantedAuthority(authority.getString("authority")));
            }
            MyUserDetails userDetails = new MyUserDetails(object.getString("username"), object.getString("password") == null ?"N/A" :object.getString("password"), grantedAuthorities);
            userDetails.setId(object.getLong("id"));
            userDetails.setExtraParam(object.getJSONObject("extraParam"));
            MyAuthenticationJWTToken myAuthenticationToken = new MyAuthenticationJWTToken(userDetails, userDetails.getAuthorities());
            return myAuthenticationToken;
        }
        return null;
    }
}
